/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Autogenerated file -- DO NOT EDIT!

#ifndef LIBABCKIT_SRC_CODEGEN_IC_FLAGS_GETTER_H
#define LIBABCKIT_SRC_CODEGEN_IC_FLAGS_GETTER_H

#include <cstdint>

#include "compiler/optimizer/ir/runtime_interface.h"

% def hasIcSlot(inst)
%   if ((inst.properties.include? "ic_slot") || (inst.properties.include? "jit_ic_slot"))
%       return true
%   end
%   return false
% end
%
% def findInvertedInst(inst)
%   Panda::instructions.select{|b| b.namespace == "ecmascript"}.each do |inverted_inst|
%       if (inst.mnemonic == inverted_inst.mnemonic && inst.opcode != inverted_inst.opcode)
%           instFormat = inst.format.pretty.upcase.gsub("PREF_", "")
%           invertedInstFormat = inverted_inst.format.pretty.upcase.gsub("PREF_", "")
%           if ((instFormat.start_with?("IMM8") && invertedInstFormat.start_with?("IMM16")) ||
%               (instFormat.start_with?("IMM16") && invertedInstFormat.start_with?("IMM8")))
%               return inverted_inst
%           end
%       end
%   end
%   return nil
% end

namespace libabckit {
    enum IcFlags : uint8_t {
        ONE_SLOT = 1U << 0U,
        TWO_SLOT = 1U << 1U,
        EIGHT_BIT_IC = 1U << 2U,
        SIXTEEN_BIT_IC = 1U << 3U,
        EIGHT_SIXTEEN_BIT_IC = 1U << 4U
    };

    // NOLINTNEXTLINE(readability-function-size)
    inline uint8_t GetIcFlags(ark::compiler::RuntimeInterface::IntrinsicId intrinsicId)
    {
        switch (intrinsicId)
        {
% Panda::instructions.select{|b| b.namespace == "ecmascript"}.each do |inst|
%   if (!hasIcSlot(inst))
%       next
%   end
%   result_ic_flags_string = ""
%   if (inst.properties.include? "one_slot")
%       result_ic_flags_string += "IcFlags::ONE_SLOT"
%   elsif (inst.properties.include? "two_slot")
%       result_ic_flags_string += "IcFlags::TWO_SLOT"
%   end
%
%   invertedInst = findInvertedInst(inst)
%   instFormat = inst.format.pretty.upcase.gsub("PREF_", "")
%   if (invertedInst != nil)
%       result_ic_flags_string += "|IcFlags::EIGHT_SIXTEEN_BIT_IC"
%   elsif (instFormat.start_with?("IMM8"))
%       result_ic_flags_string += "|IcFlags::EIGHT_BIT_IC"
%   elsif (instFormat.start_with?("IMM16"))
%       result_ic_flags_string += "|IcFlags::SIXTEEN_BIT_IC"
%   end
            case ark::compiler::RuntimeInterface::IntrinsicId::DYN_<%= inst.opcode.upcase %>:
                return <%= result_ic_flags_string %>;
% end
            default:
                return 0;
        }
    }

    // NOLINTNEXTLINE(readability-function-size)
    inline ark::compiler::RuntimeInterface::IntrinsicId GetIdWithInvertedIcImm(ark::compiler::RuntimeInterface::IntrinsicId intrinsicId)
    {
        ASSERT((GetIcFlags(intrinsicId) & IcFlags::EIGHT_SIXTEEN_BIT_IC) != 0);
        switch (intrinsicId)
        {
% Panda::instructions.select{|b| b.namespace == "ecmascript"}.each do |inst|
%   if (!hasIcSlot(inst))
%       next
%   end
%   invertedInst = findInvertedInst(inst)
%   if (invertedInst == nil)
%       next
%   end
            case ark::compiler::RuntimeInterface::IntrinsicId::DYN_<%= inst.opcode.upcase %>:
                return ark::compiler::RuntimeInterface::IntrinsicId::DYN_<%= invertedInst.opcode.upcase %>;
% end
            default:
                return ark::compiler::RuntimeInterface::IntrinsicId::INVALID;
        }
    }

    inline bool HasInstWith8Or16BitSignature8BitIcSlot(ark::compiler::RuntimeInterface::IntrinsicId intrinsicId)
    {
        ASSERT((GetIcFlags(intrinsicId) & IcFlags::EIGHT_SIXTEEN_BIT_IC) != 0);
        switch (intrinsicId)
        {
% Panda::instructions.select{|b| b.namespace == "ecmascript"}.each do |inst|
%   if (!hasIcSlot(inst))
%       next
%   end
%   invertedInst = findInvertedInst(inst)
%   if (invertedInst == nil)
%       next
%   end
%
%   if (inst.format.pretty.upcase.start_with?("IMM8"))
            case ark::compiler::RuntimeInterface::IntrinsicId::DYN_<%= inst.opcode.upcase %>:
                return true;
%   end
% end
            default:
                return false;
        }
    }
} // namespace libabckit

#endif   //LIBABCKIT_SRC_CODEGEN_IC_FLAGS_GETTER_H